package com.zlzlib.liblayoutmanager;

import android.content.Context;
import android.view.View;

/**
 * @Desc: 翻转滑动
 * @Copyright:
 * @DateTime: 2021/8/17 17:45
 * @Author zlz
 * @Version 1.0
 */
public class LayoutGalleryManager extends BaseLayoutManager {

    private final float MAX_ELEVATION = 5F;

    //每一项的间隔
    private int itemSpace;
    private float maxAlpha;
    private float minAlpha;
    //旋转角度
    private float angle;
    //item交换翻转方向
    private boolean flipRotate;
    //翻转的轴 是否绕底边
    private boolean rotateFromEdge;

    public LayoutGalleryManager(Context context) {
        this(context, 0);
    }

    public LayoutGalleryManager(Context context, int itemSpace) {
        this(context, itemSpace, HORIZONTAL);
    }

    public LayoutGalleryManager(Context context, int itemSpace, int orientation) {
        super(context, orientation, false);
        this.itemSpace = itemSpace;
        angle = 30f;
        maxAlpha = 1f;
        minAlpha = 0.5f;
        flipRotate = false;
        rotateFromEdge = false;
    }

    @Override
    protected float setInterval() {
        return mDecoratedMeasurement + itemSpace;
    }

    @Override
    protected void setItemViewProperty(View itemView, float targetOffset) {
        final float rotation = calRotation(targetOffset);
        if (getOrientation() == HORIZONTAL) {
            if (rotateFromEdge) {
                itemView.setPivotX(rotation > 0 ? 0 : mDecoratedMeasurement);
                itemView.setPivotY(mDecoratedMeasurementInOther * 0.5f);
            }
            if (flipRotate) {
                itemView.setRotationX(rotation);
            } else {
                itemView.setRotationY(rotation);
            }
        } else {
            if (rotateFromEdge) {
                itemView.setPivotY(rotation > 0 ? 0 : mDecoratedMeasurement);
                itemView.setPivotX(mDecoratedMeasurementInOther * 0.5f);
            }
            if (flipRotate) {
                itemView.setRotationY(-rotation);
            } else {
                itemView.setRotationX(-rotation);
            }
        }
        final float alpha = calAlpha(targetOffset);
        itemView.setAlpha(alpha);
    }

    @Override
    protected float setViewElevation(View itemView, float targetOffset) {
        final float ele = Math.max(Math.abs(itemView.getRotationX()), Math.abs(itemView.getRotationY())) * MAX_ELEVATION / 360;
        return MAX_ELEVATION - ele;
    }

    private float calRotation(float targetOffset) {
        return -angle / mInterval * targetOffset;
    }

    private float calAlpha(float targetOffset) {
        final float offset = Math.abs(targetOffset);
        float alpha = (minAlpha - maxAlpha) / mInterval * offset + maxAlpha;
        if (offset >= mInterval) alpha = minAlpha;
        return alpha;
    }

    public int getItemSpace() {
        return itemSpace;
    }

    public void setItemSpace(int itemSpace) {
        assertNotInLayoutOrScroll(null);
        if (this.itemSpace == itemSpace) return;
        this.itemSpace = itemSpace;
        removeAllViews();
    }

    public float getAngle() {
        return angle;
    }

    public void setAngle(float angle) {
        assertNotInLayoutOrScroll(null);
        if (this.angle == angle) return;
        this.angle = angle;
        requestLayout();
    }

    public float getMaxAlpha() {
        return maxAlpha;
    }

    public void setMaxAlpha(float maxAlpha) {
        assertNotInLayoutOrScroll(null);
        if (maxAlpha > 1) maxAlpha = 1;
        if (this.maxAlpha == maxAlpha) return;
        this.maxAlpha = maxAlpha;
        requestLayout();
    }

    public float getMinAlpha() {
        return minAlpha;
    }

    public void setMinAlpha(float minAlpha) {
        assertNotInLayoutOrScroll(null);
        if (minAlpha > 1) minAlpha = 1;
        if (this.minAlpha == minAlpha) return;
        this.minAlpha = minAlpha;
        requestLayout();
    }

    public boolean isFlipRotate() {
        return flipRotate;
    }

    public void setFlipRotate(boolean flipRotate) {
        assertNotInLayoutOrScroll(null);
        if (this.flipRotate == flipRotate) return;
        this.flipRotate = flipRotate;
        requestLayout();
    }

    public boolean isRotateFromEdge() {
        return rotateFromEdge;
    }

    public void setRotateFromEdge(boolean rotateFromEdge) {
        assertNotInLayoutOrScroll(null);
        if (this.rotateFromEdge == rotateFromEdge) return;
        this.rotateFromEdge = rotateFromEdge;
        removeAllViews();
    }
}
